package com.jf.cloud.service.sysmanager.common.db;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.persistence.Column;
import javax.persistence.Id;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * 实体解析器
 * 
 * @author 程伟平 创建时间：2014-05-17 10:30:50
 */
public class EntityParser {

	/**
	 * 日志
	 */
	private static Log log = LogFactory.getLog(EntityParser.class);

	/**
	 * 根据实体类生成 INSERT SQL语句
	 * 
	 * @author 程伟平 创建时间：2014-05-17 10:30:50
	 */
	public static <T> String getInsertSql(Class<T> clazz) {
		StringBuffer sql = new StringBuffer(512);

		String tableName = SqlUtil.getTableName(clazz);
		if (tableName != null && tableName.length() > 0) {
			StringBuffer sb1 = new StringBuffer(); // 字段SQL
			StringBuffer sb2 = new StringBuffer(); // 值SQL

			List<Field> fieldList = getFieldList(clazz, false);
			if (fieldList != null && fieldList.size() > 0) {
				for (Field field : fieldList) {
					if (sb1.length() > 0) {
						sb1.append(", ");
					}
					sb1.append(SqlUtil.getColumnName(clazz, field));

					if (sb2.length() > 0) {
						sb2.append(", ");
					}
					sb2.append("?");
				}
			}
			if (sb1 != null && sb1.length() > 0 && sb2 != null && sb2.length() > 0) {
				sql.append(" INSERT INTO ").append(tableName).append(" ( ").append(sb1).append(" ) VALUES ( ").append(sb2).append(" ) ");
			}
		}

		return sql.toString();
	}

	/**
	 * 根据实体类生成 UPDATE SQL语句
	 * 
	 * @author 程伟平 创建时间：2014-05-17 10:30:50
	 */
	public static <T> String getUpdateSql(Class<T> clazz) {
		StringBuffer sql = new StringBuffer();

		String tableName = SqlUtil.getTableName(clazz);
		if (tableName != null && tableName.length() > 0) {
			StringBuffer sb1 = new StringBuffer(); // 字段SQL
			StringBuffer sb2 = new StringBuffer(); // 条件SQL

			List<Field> fieldList = getFieldList(clazz, false);
			if (fieldList != null && fieldList.size() > 0) {
				for (Field field : fieldList) {
					if (sb1.length() > 0) {
						sb1.append(", ");
					}
					sb1.append(SqlUtil.getColumnName(clazz, field)).append(" = ?");
				}
			}

			Field pk = getPkField(clazz);
			if (pk != null) {
				sb2.append(SqlUtil.getColumnName(clazz, pk)).append(" = ?");
			}
			if (sb1 != null && sb1.length() > 0 && sb2 != null && sb2.length() > 0) {
				sql.append(" UPDATE ").append(tableName).append(" SET ").append(sb1).append(" WHERE ").append(sb2).append(" ");
			}
		}

		return sql.toString();
	}

	/**
	 * 根据实体类生成 DELETE SQL语句
	 * 
	 * @author 程伟平 创建时间：2014-05-17 10:30:50
	 */
	public static <T> String getDeleteSql(Class<T> clazz) {
		StringBuffer sql = new StringBuffer();

		String tableName = SqlUtil.getTableName(clazz);
		if (tableName != null && tableName.length() > 0) {
			StringBuffer sb1 = new StringBuffer(); // 条件SQL

			Field pk = getPkField(clazz);
			if (pk != null) {
				sb1.append(SqlUtil.getColumnName(clazz, pk)).append(" = ?");
			}
			if (sb1 != null && sb1.length() > 0) {
				sql.append(" DELETE FROM ").append(tableName).append(" WHERE ").append(sb1).append(" ");
			}
		}

		return sql.toString();
	}

	/**
	 * 根据实体类生成 SELECT SQL语句
	 * 
	 * @author 程伟平 创建时间：2014-05-17 10:30:50
	 */
	public static <T> String getSelectSql(Class<T> clazz) {
		StringBuffer sql = new StringBuffer();

		String tableName = SqlUtil.getTableName(clazz);
		if (tableName != null && tableName.length() > 0) {
			StringBuffer sb1 = new StringBuffer(); // 字段SQL

			List<Field> fieldList = getFieldList(clazz, true);
			if (fieldList != null && fieldList.size() > 0) {
				for (Field field : fieldList) {
					if (sb1.length() > 0) {
						sb1.append(", ");
					}
					sb1.append(SqlUtil.getColumnName(clazz, field));
				}
			}
			if (sb1 != null && sb1.length() > 0) {
				sql.append(" SELECT ").append(sb1).append(" FROM ").append(tableName).append(" ");
			}
		}

		return sql.toString();
	}

	/**
	 * 根据实体类获取字段列表
	 * 
	 * @author 程伟平 创建时间：2014-05-17 10:30:50
	 */
	private static <T> Field getPkField(Class<T> clazz) {
		Field pk = null;
		if (!SqlUtil.isEntityClass(clazz)) {
			throw new IllegalArgumentException("非法的实体类【" + clazz + "】！");
		}
		Field[] fields = clazz.getDeclaredFields();
		if (fields != null && fields.length > 0) {
			for (Field field : fields) {
				if (field.isAnnotationPresent(Id.class)) {
					pk = field;
					break;
				}
			}
		}
		return pk;
	}

	/**
	 * 根据实体类获取字段列表
	 * 
	 * @author 程伟平 创建时间：2014-05-17 10:30:50
	 */
	private static <T> List<Field> getFieldList(Class<T> clazz, boolean pkFlag) {
		List<Field> list = new ArrayList<Field>();
		if (!SqlUtil.isEntityClass(clazz)) {
			throw new IllegalArgumentException("非法的实体类【" + clazz + "】！");
		}
		Field[] fields = clazz.getDeclaredFields();
		if (fields != null && fields.length > 0) {
			for (Field field : fields) {
				// 主键
				if (pkFlag) {
					if (field.isAnnotationPresent(Id.class)) {
						list.add(field);
					}
				} else {
					if (field.isAnnotationPresent(Id.class)) {
						continue;
					}
				}
				// 普通属性
				if (field.isAnnotationPresent(Column.class)) {
					list.add(field);
				}
			}
		}
		return list;
	}

	/**
	 * 根据实体对象获取字段值列表
	 * 
	 * @author 程伟平 创建时间：2014-05-17 10:30:50
	 */
	public static <T> List<Object> getValueList(T o, boolean pkFlag) {
		Class<?> clazz = o.getClass();
		if (!SqlUtil.isEntityClass(clazz)) {
			throw new IllegalArgumentException("非法的实体类【" + clazz + "】！");
		}

		List<Object> list = new ArrayList<Object>();
		try {
			List<Field> fieldList = getFieldList(clazz, pkFlag);
			if (fieldList != null && fieldList.size() > 0) {
				for (Field field : fieldList) {
					list.add(getValue(o, field));
				}
			}
		} catch (Exception e) {
			log.error("根据实体对象获取字段值列表出错了！", e);
		}
		return list;
	}

	/**
	 * 根据实体对象，实体类属性获取属性值
	 * 
	 * @author 程伟平 创建时间：2014-05-20 09:27:12
	 */
	public static <T> Object getValue(T o, Field field) {
		Object value = null;
		try {
			// 属性名称
			String fieldName = field.getName();
			// 方法名称
			String methodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
			value = o.getClass().getMethod(methodName).invoke(o);
		} catch (Exception e) {
			log.error("根据实体对象，实体类属性获取属性值出错了！", e);
		}
		return value;
	}

	/**
	 * 根据实体对象，实体类属性设置属性值
	 * 
	 * @author 程伟平 创建时间：2014-05-20 09:27:12
	 */
	public static <T> void setValue(T o, Field field, Object value) {
		try {
			// 属性名称
			String fieldName = field.getName();
			// 方法名称
			String methodName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
			o.getClass().getMethod(methodName, field.getType()).invoke(o, value);
		} catch (Exception e) {
			log.error("根据实体对象，实体类属性获取属性值出错了！", e);
		}
	}

	/**
	 * 获取实体对象主键字段值
	 * 
	 * @author 程伟平 创建时间：2014-05-17 10:30:50
	 */
	public static <T> Object getPkValue(T o) {
		Object value = null;
		try {
			Field field = getPkField(o.getClass());
			value = getValue(o, field);
		} catch (Exception e) {
			log.error("获取实体对象主键字段值出错了！", e);
		}
		return value;
	}

	/**
	 * 设置实体对象字段值
	 * 
	 * @author 程伟平 创建时间：2014-05-17 10:30:50
	 */
	public static <T> void setPkValue(T o, Object value) {
		try {
			Field field = getPkField(o.getClass());
			setValue(o, field, value);
		} catch (Exception e) {
			log.error("设置实体对象主键字段值出错了！", e);
		}
	}

}
